using System;
using System.Collections.Generic;
using System.Text;
using Fieldbook.DAL;
using System.Data.Common;
using Fieldbook.Common;
using Microsoft.Practices.EnterpriseLibrary.Data.Sql;
using Fieldbook.Entities;
using System.Security.Cryptography;


namespace Fieldbook.Business
{
    public static class AppUserController
    {
        public static void RegisterNewUser(Appuser user, long? headID)
        {
            DbTransaction transaction = null;
            try
            {
                bool enabledMail = Boolean.Parse(AppSettingsHelper.GetConfigValue(Constants.EnableMail));
                
                /* retreive administrators */
                string criteria = String.Format(" WHERE POSTALCODE = '{0}' AND RoleID = {1}", user.Postalcode, (int)Appuser.Role.Admin);
                List<Appuser> admins = AppuserDAO.LoadAppusers(criteria, "");
                if (admins.Count == 0) // no admins for particular zip code
                {
                    criteria = String.Format(" WHERE RoleID = {0}", (int)Appuser.Role.SuperAdmin); // sending message to superadmins
                    admins = AppuserDAO.LoadAppusers(criteria, "");
                }

                SqlDatabase db = Utilities.GetDatabase();
                transaction = Utilities.BeginTransaction(db);
                
                /* inserting the new user */
                user.Roleid = Appuser.Role.User;
                user.Statusid = Appuser.Status.New;
                byte[] originalbytes = ASCIIEncoding.ASCII.GetBytes(user.Password);
                MD5 md5 = new MD5CryptoServiceProvider();
                byte[] encodedBytes = md5.ComputeHash(originalbytes);
                user.Password = BitConverter.ToString(encodedBytes);
                AppuserDAO.InsertAppuser(user, transaction, db);
                
                /* sendig message to the admins that new user wants to register */
                Message message = new Message();
                message.Caption = "New user registration request";
                message.Messagetypeid = Message.MessageType.SimpleMessage;
                message.Messagestatusid = Message.MessageStatus.Delivered;
                message.Messagereadstatus = false;
                message.Content = String.Format(@"New user has has applied for using fieldbook system. Check your profile to approve or dissaprove status for {0} {1}"
                                                ,user.Firstname, user.Lastname);
                for (int i = 0; i < admins.Count; i++)
                {
                    message.Receiverid = admins[i].Userid;
                    MessageDAO.InsertMessage(message, transaction, db);
                    if (enabledMail && admins[i].ReceiveMail)
                    {
                        message.Messagetypeid = Message.MessageType.Mail;
                        message.Messagestatusid = Message.MessageStatus.Pending;
                        MessageDAO.InsertMessage(message, transaction, db);
                    }
                }

                /* adding a Household information */
                Household hHold = new Household();
                hHold.Headid = (headID == null) ? user.Userid : headID;
                hHold.Memberid = user.Userid;
                HouseholdDAO.InsertHousehold(hHold, transaction, db);

                transaction.Commit();
            }
            catch (Exception ex)
            {
                if (transaction != null) { transaction.Rollback(); }
                LogManager.LogException("Error registering new user", ex);
            }
            finally
            {
                Utilities.EndTransaction(transaction);
            }
        }

        public static void ApproveNewUser(Appuser user)
        {
            DbTransaction transaction = null;
            try
            {
                bool enabledMail = Boolean.Parse(AppSettingsHelper.GetConfigValue(Constants.EnableMail));
                
                /* retreive household head */
                Household hHold = HouseholdDAO.LoadHouseholds(String.Format(" WHERE MemberID = {0}", user.Userid), "")[0];

                SqlDatabase db = Utilities.GetDatabase();
                transaction = Utilities.BeginTransaction(db);
                user.Statusid = Appuser.Status.Active;
                AppuserDAO.UpdateAppuser(user, transaction, db);

                Message message = new Message();
                message.Receiverid = user.Userid;
                message.Messagetypeid = Message.MessageType.SimpleMessage;
                message.Messagereadstatus = false;
                message.Messagestatusid = Message.MessageStatus.Delivered; 
                message.Caption = "Welcome to fieldbook";
                message.Content = "blah blah blah new user, welocme to fieldbook";
                MessageDAO.InsertMessage(message, transaction, db);
                if (enabledMail && user.ReceiveMail)
                {
                    message.Messagetypeid = Message.MessageType.Mail;
                    message.Messagestatusid = Message.MessageStatus.Pending;
                    MessageDAO.InsertMessage(message, transaction, db);
                }

                /* user has joined to another household */
                if (hHold.Headid != user.Userid)
                {
                    Appuser houseHead = AppuserDAO.LoadAppusers(String.Format(" WHERE UserID = {0} ", hHold.Headid), "")[0];
                    message.Receiverid = hHold.Headid;
                    message.Messagetypeid = Message.MessageType.SimpleMessage;
                    message.Messagereadstatus = false;
                    message.Messagestatusid = Message.MessageStatus.Delivered;
                    message.Caption = "new member of the household";
                    message.Content = "Blah blah blah, new member of the house hold arrived";
                    MessageDAO.InsertMessage(message, transaction, db);
                    if (enabledMail && houseHead.ReceiveMail)
                    {
                        message.Messagetypeid = Message.MessageType.Mail;
                        message.Messagestatusid = Message.MessageStatus.Pending;
                        MessageDAO.InsertMessage(message, transaction, db);
                    }
                }
                transaction.Commit();
            }
            catch (Exception ex)
            {
                if (transaction != null) { transaction.Rollback(); }
                LogManager.LogException("Error registering new user", ex);
            }
            finally
            {
                Utilities.EndTransaction(transaction);
            }
        }

        public static Appuser LoginUser(string userName, string password)
        {
            Appuser user = null;
            try
            {
                byte[] originalbytes = ASCIIEncoding.ASCII.GetBytes(password);
                MD5 md5 = new MD5CryptoServiceProvider();
                byte[] encodedBytes = md5.ComputeHash(originalbytes);
                string encodedPass = BitConverter.ToString(encodedBytes);
                string criteria = String.Format(" WHERE USERNAME = '{0}' AND PASSWORD = '{1}' AND STATUS = {2}", 
                    userName, encodedPass,(int)Appuser.Status.Active);

                List<Appuser> users = AppuserDAO.LoadAppusers(criteria, "");
                if (users.Count != 0)
                {
                    user = users[0];
                }
            }
            catch (Exception ex)
            {
                LogManager.LogException("Error logg in user", ex);
            }
            return user;
        }

        public static bool CheckLoginUser(string userName, string password)
        {
            bool res = false;
            try
            {
                byte[] originalbytes = ASCIIEncoding.ASCII.GetBytes(password);
                MD5 md5 = new MD5CryptoServiceProvider();
                byte[] encodedBytes = md5.ComputeHash(originalbytes);
                string encodedPass = BitConverter.ToString(encodedBytes);
                string criteria = String.Format(" WHERE USERNAME = '{0}' AND PASSWORD = '{1}' AND STATUS = {2}", 
                    userName, encodedPass, (int)Appuser.Status.Active);
                
                List<long> userIDs = AppuserDAO.GetUserIds(criteria);
                res = userIDs.Count == 1;
           }
            catch (Exception ex)
            {
                LogManager.LogException("Error logg in user", ex);
            }
            return res;
        }

        public static List<Appuser> LoadHouseHoldUsers(long userID)
        {
            List<Appuser> res = null;
            try
            {
                res = AppuserDAO.LoadHouseHoldUsers(userID);
            }
            catch (Exception ex)
            {
                LogManager.LogException("Error logg in user", ex);
            }
            return res;
        }

        public static long? GetHoueHoldID(long userID)
        {
            long? res = null;
            try
            {
                res = HouseholdDAO.GetHouseHoldID(userID);
            }
            catch (Exception ex)
            {
                LogManager.LogException("Error loading household", ex);
            }
            return res;
        }
    }
}
